import { API_CONFIG, HTTP_STATUS, BUSINESS_CODE } from './config.js';
import { ElMessage } from 'element-plus';

// 请求拦截器
const requestInterceptor = (config) => {
  // 添加认证token
  console.log('request  Token 测试')
  const token = localStorage.getItem('satoken');

  if (token) {
    config.headers = {
      ...config.headers,
      // 1. 修复：移除 satoken 前面的空格，避免格式错误
      'satoken': token,
      // 注：如果后端用 Bearer 认证则保留 Authorization，否则可删除（避免冗余）
      'Authorization': `Bearer ${token}`,
    };
  }
console.log(config.headers)
  // 添加时间戳防止缓存
  if (config.method === 'get') {
    config.params = {
      ...config.params,
      _t: Date.now()
    };
  }

  console.log('API Request:', config.method?.toUpperCase(), config.url, config.data || config.params);
  return config;
};

// 响应拦截器
const responseInterceptor = (response) => {
  console.log('API Response:', response.status, response.data);

  // 处理成功响应
  if (response.status >= 200 && response.status < 300) {
    return response.data;
  }

  // 处理HTTP错误
  throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
};

// 错误处理
const errorHandler = (error) => {
  console.error('API Error:', error);

  let message = '网络请求失败';

  if (error.response) {
    // 服务器响应了错误状态码
    const { status, data } = error.response;

    switch (status) {
      case HTTP_STATUS.UNAUTHORIZED:
        message = '登录已过期，请重新登录';
        // 清除token并跳转到登录页
        localStorage.removeItem('satoken');
        // 这里可以添加路由跳转逻辑
        break;
      case HTTP_STATUS.FORBIDDEN:
        message = '没有权限访问该资源';
        break;
      case HTTP_STATUS.NOT_FOUND:
        message = '请求的资源不存在';
        break;
      case HTTP_STATUS.INTERNAL_ERROR:
        message = '服务器内部错误';
        break;
      default:
        message = data?.message || `请求失败 (${status})`;
    }
  } else if (error.request) {
    // 请求已发出但没有收到响应
    message = '网络连接失败，请检查网络设置';
  } else {
    // 请求配置出错
    message = error.message || '请求配置错误';
  }

  ElMessage.error(message);
  return Promise.reject(error);
};

// 创建请求实例
const createRequest = (config) => {
  const { url, method = 'GET', data, params, headers = {}, timeout = API_CONFIG.TIMEOUT } = config;

  // 构建完整URL
  let fullUrl;
  if (url.startsWith('http')) {
    fullUrl = url;
  } else if (API_CONFIG.BASE_URL === '/api') {
    // 开发环境：使用代理
    fullUrl = `${API_CONFIG.BASE_URL}${url}`;
  } else {
    // 生产环境：直接拼接完整URL
    fullUrl = `${API_CONFIG.BASE_URL}${url}`;
  }

  // 合并请求头 - 关键修改：如果是FormData则不设置默认Content-Type
  const requestHeaders = {
    ...(data instanceof FormData ? {} : API_CONFIG.HEADERS),
    ...headers
  };

  // 构建fetch配置
  const fetchConfig = {
    method: method.toUpperCase(),
    headers: requestHeaders,
    timeout: timeout,
  };

  // 添加请求体 - 关键修改：FormData不需要JSON.stringify
  if (data && method.toUpperCase() !== 'GET') {
    fetchConfig.body = data instanceof FormData ? data : JSON.stringify(data);
  }

  // 添加查询参数
  let finalUrl = fullUrl;
  if (params && Object.keys(params).length > 0) {
    const searchParams = new URLSearchParams();
    Object.entries(params).forEach(([key, value]) => {
      if (value !== undefined && value !== null) {
        searchParams.append(key, value);
      }
    });
    finalUrl += `?${searchParams.toString()}`;
  }

  // 应用请求拦截器
  const interceptedConfig = requestInterceptor({
    url: finalUrl,
    method: method.toUpperCase(),
    headers: requestHeaders,
    data,
    params
  });

  // 创建AbortController用于超时控制
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  return fetch(interceptedConfig.url, {
    ...fetchConfig,
    signal: controller.signal
  })
      .then(response => {
        clearTimeout(timeoutId);

        // 检查响应状态
        if (!response.ok) {
          throw {
            response: {
              status: response.status,
              statusText: response.statusText,
              data: null
            }
          };
        }

        // 解析响应数据
        const contentType = response.headers.get('content-type');
        if (contentType && contentType.includes('application/json')) {
          return response.json();
        } else {
          return response.text();
        }
      })
      .then(data => {
        // 应用响应拦截器
        return responseInterceptor({ status: 200, data });
      })
      .catch(error => {
        clearTimeout(timeoutId);

        // 处理AbortError（超时）
        if (error.name === 'AbortError') {
          throw {
            message: '请求超时，请稍后重试',
            isTimeout: true
          };
        }

        return errorHandler(error);
      });
};

// 封装常用请求方法
export const request = {
  // GET请求
  get: (url, params, config = {}) => {
    return createRequest({
      url,
      method: 'GET',
      params,
      ...config
    });
  },

  // POST请求
  post: (url, data, config = {}) => {
    return createRequest({
      url,
      method: 'POST',
      data,
      ...config
    });
  },

  // PUT请求
  put: (url, data, config = {}) => {
    return createRequest({
      url,
      method: 'PUT',
      data,
      ...config
    });
  },

  // DELETE请求
  delete: (url, config = {}) => {
    return createRequest({
      url,
      method: 'DELETE',
      ...config
    });
  },

  // 文件上传 - 优化上传配置
  upload: (url, formData, config = {}) => {
    // 确保传入的是FormData对象
    if (!(formData instanceof FormData)) {
      throw new Error('upload方法要求第二个参数必须是FormData对象');
    }

    return createRequest({
      url,
      method: 'POST',
      data: formData,
      // 关键：不设置Content-Type，让浏览器自动处理
      headers: {
        ...config.headers
      },
      ...config
    });
  },

  // 文件下载
  download: (url, params, filename, config = {}) => {
    return createRequest({
      url,
      method: 'GET',
      params,
      ...config
    }).then(data => {
      // 创建下载链接
      const blob = new Blob([data]);
      const downloadUrl = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = downloadUrl;
      link.download = filename;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(downloadUrl);
      return data;
    });
  }
};

export default request;
